﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using UofCASE.AgileProductLinerDSL;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VsSDK.UnitTestLibrary;
using System.ComponentModel.Design;
using System.Collections;
using Microsoft.VisualStudio.Modeling;
using UofCASE.GreenPepe.Extensibility;
using Microsoft.VisualStudio.Modeling.Diagrams;


namespace APLDTests {
    [TestClass]
    public class CommandTest {
        //[TestMethod]
        public void TestMethod() {

            IVsPackage package = new AgileProductLinerDSLPackage() as IVsPackage;

            OleServiceProvider serviceProvider = OleServiceProvider.CreateOleServiceProviderWithBasicServices();

            AgileProductLinerDSLCommandSet cmdSet = new AgileProductLinerDSLCommandSet(serviceProvider);
            
        }

        [TestMethod]
        public void TestCheckMappingCommandStatus() {
            ModelHelper model = ModelHelper.GetModel(true);
            MenuCommand command = new MenuCommand(null, null);
            IList<ModelElement> selection = new List<ModelElement>();
            selection.Add(model.GetElement<ModelElement>("testShape"));
            selection.Add(model.GetElement<ModelElement>("testShape2"));
            CommandHandler.CheckMappingCommandStatus(command, selection as ICollection);
            Assert.IsFalse(command.Visible);
            Assert.IsFalse(command.Enabled);

            selection.RemoveAt(1);
            CommandHandler.CheckMappingCommandStatus(command, selection as ICollection);
            Assert.IsTrue(command.Visible);
            Assert.IsTrue(command.Enabled);

            selection.RemoveAt(0);
            selection.Add(model.GetElement<ModelElement>("testCon"));
            CommandHandler.CheckMappingCommandStatus(command, selection as ICollection);
            Assert.IsFalse(command.Visible);
            Assert.IsFalse(command.Enabled);
        }

        [TestMethod]
        public void TestCheckUnmappingCommandVisibility() {
            ModelHelper model = ModelHelper.GetModel(true);
            MenuCommand command = new MenuCommand(null, null);
            IList<ModelElement> selection = new List<ModelElement>();
            selection.Add(model.GetElement<ModelElement>("testShape"));
            selection.Add(model.GetElement<ModelElement>("testShape2"));
            CommandHandler.CheckUnmappingCommandStatus(command, selection as ICollection);
            Assert.IsFalse(command.Visible);
            Assert.IsFalse(command.Enabled);

            selection.RemoveAt(1);
            CommandHandler.CheckUnmappingCommandStatus(command, selection as ICollection);
            Assert.IsFalse(command.Visible);
            Assert.IsFalse(command.Enabled);

            using (Transaction t = model.Store.TransactionManager.BeginTransaction("map test")){
                Test test = model.GetElement<Test>("test");
                test.IsMapped = true;
                t.Commit();
            }
            CommandHandler.CheckUnmappingCommandStatus(command, selection as ICollection);
            Assert.IsTrue(command.Visible);
            Assert.IsTrue(command.Enabled);

            selection.RemoveAt(0);
            selection.Add(model.GetElement<ModelElement>("testCon"));
            CommandHandler.CheckUnmappingCommandStatus(command, selection as ICollection);
            Assert.IsFalse(command.Visible);
            Assert.IsFalse(command.Enabled);
        }

        [TestMethod]
        public void TestMapUnmapTestCommand() {
            ModelHelper model = ModelHelper.GetModel(true);
            TestShape testShape = model.GetElement<TestShape>("testShape");
            Test test = model.GetElement<Test>("test");
            Assert.IsFalse(test.IsMapped);
            Assert.AreEqual(APLDRessources.NoTestMapped, test.Name);
            CommandHandler.MapTest(testShape, @"Project\Folder\Test.html", @"Project\Project.csproj");
            Assert.IsTrue(test.IsMapped);
            Assert.AreEqual("Test", test.Name);
            Assert.AreEqual(@"Project\Folder\Test.html", test.RelativePath);
            Assert.AreEqual(@"Project\Project.csproj", test.ProjectUniqueName);
            CommandHandler.UnmapTest(testShape);
            Assert.IsFalse(test.IsMapped);
            Assert.AreEqual("Test", test.Name);
            Assert.AreEqual("", test.RelativePath);
            Assert.AreEqual("", test.ProjectUniqueName);
        }

        [TestMethod]
        public void TestImportUnmappedTestsCommand() {
            ModelHelper model = ModelHelper.GetModel(true);

            int numberOfElementsBefore = model.Store.ElementDirectory.AllElements.Count;
            int numberOfTestsBefore = model.Store.ElementDirectory.FindElements<Test>().Count;

            GreenPepeConnector connector = new GreenPepeConnector(new MockGreenPepeService(2));
            IList<TestInformation> unmappedTests = connector.GetAllUnmappedTests(model.Store);

            CommandHandler.ImportUnmappedTests(model.Store, connector);

            int numberOfElementsAfter = model.Store.ElementDirectory.AllElements.Count;
            int numberOfTestsAfter = model.Store.ElementDirectory.FindElements<Test>().Count;

            Assert.AreEqual(8, numberOfElementsAfter - numberOfElementsBefore);
            Assert.AreEqual(2, numberOfTestsAfter - numberOfTestsBefore);

            IList<Test> tests = model.Store.ElementDirectory.FindElements<Test>();
            Test test = tests.Last<Test>();
            Assert.AreEqual(test.RelativePath, unmappedTests.Last().RelativePath);
        }

        //[TestMethod]
        public void TestRunAllTestsCommand() {
            // TODO Interface for GP.Test and mock
            ModelHelper model = ModelHelper.GetModel(true);
            GreenPepeConnector connector = new GreenPepeConnector(new MockGreenPepeService(2));
            
            IList<Object> selection = new List<Object>();
            selection.Add(model.GetElement<NodeShape>("featureShape"));
            CommandHandler.RunAllTests(connector, (ICollection)selection);
        }
    }
}
